Micron Document
πŸŽ–οΈGitΠ―Ρ€Π°πŸŽ–οΈ


Displaying Rendered β€’ View raw β€’ Download

specs/005-tak-v2-protocol/tasks.md bd2863243bab6eb213401d949839a2bc74dde7e2 (bd286324) Text, 20.74 KB

Tasks: TAK v2 Protocol Integration

Input: Design documents from T383838/specs/005-tak-v2-protocol/
Prerequisites: plan.md βœ…, spec.md βœ…, research.md βœ…, data-model.md βœ…, contracts/ βœ…
Status: Retroactive β€” documents work completed in PR #5434 (99 files, +4698 lines). Use as verification checklist.

Tests: Included β€” the implementation ships with 12 test classes and 89+ test methods covering all CoT types.

Verification: Constitution-required validation tasks included (spotlessCheck, detekt, compile, allTests).

Format: T383838[ID] [P?] [Story] Description

β€’ [P]: Can run in parallel (different files, no dependencies)
β€’ [Story]: Which user story this task belongs to (e.g., US1, US2, US3)
β€’ Include exact file paths in descriptions


Phase 1: Setup (Module & Dependencies)

Purpose: Create the T383838core:takserver KMP module, configure dependencies, and establish project structure.

β€’ [X] T001 Create T383838core/takserver/build.gradle.kts with TAKPacket-SDK v0.1.3, xmlutil, zstd-jni 1.5.7-7, Ktor Network, Okio, Koin, and Kermit dependencies
β€’ [X] T002 Register T383838:core:takserver module in T383838settings.gradle.kts
β€’ [X] T003 [P] Create source set directory structure: T383838commonMain, T383838commonTest, T383838jvmAndroidMain, T383838androidMain, T383838jvmMain, T383838iosMain under T383838core/takserver/src/
β€’ [X] T004 [P] Add bundled mTLS certificates to T383838core/takserver/src/jvmAndroidMain/resources/tak_certs/
β€’ [X] T005 [P] Add 40 CoT XML test fixture files to T383838core/takserver/src/jvmAndroidMain/resources/tak_test_fixtures/
β€’ [X] T006 [P] Create Koin DI module in T383838core/takserver/src/commonMain/kotlin/org/meshtastic/core/takserver/di/CoreTakServerModule.kt


Phase 2: Foundational (Shared Models, Constants & Utilities)

Purpose: Core domain models, constants, and utilities that ALL user stories depend on.

⚠️ CRITICAL: No user story work can begin until this phase is complete.

β€’ [X] T007 Define domain models (CoTMessage, CoTContact, CoTGroup, CoTStatus, CoTTrack, CoTChat, TAKClientInfo, InboundCoTMessage) in T383838core/takserver/src/commonMain/kotlin/.../TAKModels.kt
β€’ [X] T008 [P] Define constants (DEFAULTTAKPORT, MAXTAKWIREPAYLOADBYTES, MAXDECOMPRESSEDSIZE, TAKCOORDINATESCALE, DICTIDs, OFFLINEQUEUETTL, KEEPALIVEINTERVAL, MINMESHSTALE_TTL) in T383838core/takserver/src/commonMain/kotlin/.../TAKDefaults.kt
β€’ [X] T009 [P] Implement XML escaping utilities (5 special characters: &, <, >, ", ') in T383838core/takserver/src/commonMain/kotlin/.../XmlUtils.kt
β€’ [X] T010 [P] Implement CoT XML data classes for serialization in T383838core/takserver/src/commonMain/kotlin/.../CoTXmlDataClasses.kt
β€’ [X] T011 [P] Implement ATAK preference XML schema classes in T383838core/takserver/src/commonMain/kotlin/.../TAKPrefXmlDataClasses.kt
β€’ [X] T012 [P] Implement shared coordinate scaling and conversion helpers in T383838core/takserver/src/commonMain/kotlin/.../TakConversionHelpers.kt
β€’ [X] T013 [P] Implement T383838TakV2TypeMapper with 23 CoT types + 4 HOW types + CotType_Other fallback in T383838core/takserver/src/commonMain/kotlin/.../TakV2TypeMapper.kt
β€’ [X] T014 [P] Implement T383838CoTDetailStripper to strip 16 bloat XML elements (regex-based) in T383838core/takserver/src/commonMain/kotlin/.../CoTDetailStripper.kt
β€’ [X] T015 [P] Implement streaming T383838CoTXmlParser (XML β†’ CoTMessage) in T383838core/takserver/src/commonMain/kotlin/.../CoTXmlParser.kt
β€’ [X] T016 [P] Implement T383838CoTXml (CoTMessage β†’ XML serialization) in T383838core/takserver/src/commonMain/kotlin/.../CoTXml.kt
β€’ [X] T017 [P] Implement TCP stream framing in T383838core/takserver/src/commonMain/kotlin/.../CoTXmlFrameBuffer.kt
β€’ [X] T018 [P] Implement shared conversion helpers in T383838core/takserver/src/commonMain/kotlin/.../CoTConversion.kt
β€’ [X] T019 [P] Add T383838supportsTakV2 capability flag (firmware >= 2.8.0 check) in T383838core/model/src/commonMain/kotlin/.../Capabilities.kt
β€’ [X] T020 [P] Define T383838AtakFileWriter expect interface in T383838core/takserver/src/commonMain/kotlin/.../AtakFileWriter.kt
β€’ [X] T021 [P] Define T383838ZipArchiver expect interface in T383838core/takserver/src/commonMain/kotlin/.../ZipArchiver.kt
β€’ [X] T022 [P] Define T383838TakFixtureLoader expect interface in T383838core/takserver/src/commonMain/kotlin/.../TakFixtureLoader.kt
β€’ [X] T023 [P] Define T383838TakV2Compressor expect interface in T383838core/takserver/src/commonMain/kotlin/.../TakV2Compressor.kt
β€’ [X] T024 [P] Define T383838TAKServer expect interface in T383838core/takserver/src/commonMain/kotlin/.../TAKServer.kt

Checkpoint: Foundation ready β€” all shared types, constants, and interfaces established.


Phase 3: User Story 1 β€” Send Rich Tactical Data Over Mesh (Priority: P1) 🎯 MVP

Goal: Convert all CoT types from ATAK clients into compressed TAKPacketV2 and transmit over port 78. Receiving nodes decompress and forward to connected TAK clients.

Independent Test: Drop a hostile marker on one ATAK instance β†’ appears on remote ATAK with correct type, icon, and position.

Tests for User Story 1

β€’ [X] T025 [P] [US1] Implement T383838CoTXmlParserTest (XML parsing for all 23 CoT types) in T383838core/takserver/src/commonTest/kotlin/.../CoTXmlParserTest.kt
β€’ [X] T026 [P] [US1] Implement T383838CoTXmlTest (CoTMessage β†’ XML round-trip) in T383838core/takserver/src/commonTest/kotlin/.../CoTXmlTest.kt
β€’ [X] T027 [P] [US1] Implement T383838CoTConversionTest (conversion helper correctness) in T383838core/takserver/src/commonTest/kotlin/.../CoTConversionTest.kt
β€’ [X] T028 [P] [US1] Implement T383838CoTDetailStripperTest (16-element stripping) in T383838core/takserver/src/commonTest/kotlin/.../CoTDetailStripperTest.kt
β€’ [X] T029 [P] [US1] Implement T383838TAKPacketV2RawDetailTest (raw_detail round-trip for shapes/markers/routes) in T383838core/takserver/src/commonTest/kotlin/.../TAKPacketV2RawDetailTest.kt
β€’ [X] T030 [P] [US1] Implement T383838XmlUtilsTest (escaping correctness for 5 special chars) in T383838core/takserver/src/commonTest/kotlin/.../XmlUtilsTest.kt
β€’ [X] T031 [P] [US1] Implement T383838TAKDefaultsTest (constants validation) in T383838core/takserver/src/commonTest/kotlin/.../TAKDefaultsTest.kt

Implementation for User Story 1

β€’ [X] T032 [US1] Implement T383838TAKPacketV2Conversion (CoTMessage ↔ TAKPacketV2 for all CoT types including pli, chat, raw_detail payloads) in T383838core/takserver/src/commonMain/kotlin/.../TAKPacketV2Conversion.kt
β€’ [X] T033 [P] [US1] Implement T383838TakV2Compressor actual (zstd dictionary compression via TAKPacket-SDK) in T383838core/takserver/src/jvmAndroidMain/kotlin/.../TakV2Compressor.kt
β€’ [X] T034 [P] [US1] Implement T383838TakV2Compressor iOS stub (uncompressed, flags=0xFF) in T383838core/takserver/src/iosMain/kotlin/.../TakV2Compressor.kt
β€’ [X] T035 [US1] Implement T383838RouteDataPackageGenerator (Route CoT β†’ KML data package with MissionPackageManifest v2) in T383838core/takserver/src/commonMain/kotlin/.../RouteDataPackageGenerator.kt
β€’ [X] T036 [US1] Implement T383838TAKMeshIntegration outbound path (TAK client β†’ CoT parse β†’ detail strip β†’ compress β†’ MTU check β†’ port 78 send) in T383838core/takserver/src/commonMain/kotlin/.../TAKMeshIntegration.kt
β€’ [X] T037 [US1] Implement T383838TAKMeshIntegration inbound path (port 78 receive β†’ decompress β†’ decode β†’ broadcast to TAK clients) in T383838core/takserver/src/commonMain/kotlin/.../TAKMeshIntegration.kt
β€’ [X] T038 [P] [US1] Implement T383838TakFixtureLoader actual (JVM resource loading for test fixtures) in T383838core/takserver/src/jvmAndroidMain/kotlin/.../TakFixtureLoader.kt
β€’ [X] T039 [P] [US1] Implement T383838TakFixtureLoader iOS stub in T383838core/takserver/src/iosMain/kotlin/.../TakFixtureLoader.kt
β€’ [X] T040 [P] [US1] Implement T383838ZipArchiver actual (java.util.zip) in T383838core/takserver/src/jvmAndroidMain/kotlin/.../ZipArchiver.kt
β€’ [X] T041 [P] [US1] Implement T383838ZipArchiver iOS stub in T383838core/takserver/src/iosMain/kotlin/.../ZipArchiver.kt
β€’ [X] T042 [P] [US1] Implement T383838AtakFileWriter actual (SAF/private directory) in T383838core/takserver/src/androidMain/kotlin/.../AtakFileWriter.kt
β€’ [X] T043 [P] [US1] Implement T383838AtakFileWriter actual (desktop filesystem) in T383838core/takserver/src/jvmMain/kotlin/.../AtakFileWriter.kt
β€’ [X] T044 [P] [US1] Implement T383838AtakFileWriter iOS stub in T383838core/takserver/src/iosMain/kotlin/.../AtakFileWriter.kt
β€’ [X] T045 [US1] Implement T383838TakMeshTestRunner (in-app diagnostic runner for per-CoT-type byte size and round-trip verification) in T383838core/takserver/src/commonMain/kotlin/.../TakMeshTestRunner.kt

Checkpoint: All 28 CoT type mappings encode/decode correctly. Compressed PLI < 100 bytes. Shapes/markers/routes fit within 225-byte MTU after stripping + compression.


Phase 4: User Story 2 β€” Legacy Fallback for Mixed Firmware (Priority: P1)

Goal: Auto-detect firmware version and use TAKPacket v1 (port 72) for radios < 2.8.0. Drop unsupported CoT types on legacy with a warning. Always accept inbound on both ports.

Independent Test: Connect a node with firmware 2.7.x and verify PLI/GeoChat work on port 72 while markers are dropped with warning.

Tests for User Story 2

β€’ [X] T046 [P] [US2] Implement T383838TAKPacketConversionTest (v1 PLI + GeoChat encode/decode) in T383838core/takserver/src/commonTest/kotlin/.../TAKPacketConversionTest.kt

Implementation for User Story 2

β€’ [X] T047 [US2] Implement T383838TAKPacketConversion (CoTMessage ↔ TAKPacket v1 for PLI and GeoChat only) in T383838core/takserver/src/commonMain/kotlin/.../TAKPacketConversion.kt
β€’ [X] T048 [US2] Implement version-gating logic in T383838TAKMeshIntegration β€” check T383838Capabilities.supportsTakV2 per-send to select port 72 vs port 78 path in T383838core/takserver/src/commonMain/kotlin/.../TAKMeshIntegration.kt
β€’ [X] T049 [US2] Implement dual-port inbound listener in T383838TAKMeshIntegration β€” accept and decode packets from both port 72 and port 78 regardless of local firmware in T383838core/takserver/src/commonMain/kotlin/.../TAKMeshIntegration.kt
β€’ [X] T050 [US2] Implement CoT type filtering for legacy path β€” drop non-PLI/non-GeoChat types with logged warning on firmware < 2.8.0 in T383838core/takserver/src/commonMain/kotlin/.../TAKMeshIntegration.kt

Checkpoint: Mixed-firmware mesh maintains PLI/GeoChat for legacy nodes. Advanced CoT types dropped cleanly with user-visible warning.


Phase 5: User Story 3 β€” TAK Server Lifecycle and Reliability (Priority: P2)

Goal: Run a reliable local TLS/mTLS server on port 8089, maintain ATAK/iTAK connections through screen-off and Doze mode, support data package export.

Independent Test: Enable TAK server, connect ATAK via exported data package, verify connection persists for 10+ minutes with screen off.

Tests for User Story 3

β€’ [X] T051 [P] [US3] Implement T383838CoTXmlFrameBufferTest (TCP stream framing correctness) in T383838core/takserver/src/commonTest/kotlin/.../CoTXmlFrameBufferTest.kt

Implementation for User Story 3

β€’ [X] T052 [US3] Implement T383838TAKServerJvm actual (JSSE SSLServerSocket with mTLS on port 8089) in T383838core/takserver/src/jvmAndroidMain/kotlin/.../TAKServerJvm.kt
β€’ [X] T053 [P] [US3] Implement T383838TAKServerIos actual (no-op stub) in T383838core/takserver/src/iosMain/kotlin/.../TAKServerIos.kt
β€’ [X] T054 [US3] Implement T383838TAKClientConnection (per-client coroutine scope, SupervisorJob, BufferedOutputStream + writeMutex, XML stream framing) in T383838core/takserver/src/jvmAndroidMain/kotlin/.../TAKClientConnection.kt
β€’ [X] T055 [US3] Implement T383838TakCertLoader (load bundled .p12/.pem certificates for mTLS) in T383838core/takserver/src/jvmAndroidMain/kotlin/.../TakCertLoader.kt
β€’ [X] T056 [US3] Implement T383838TAKServerManager lifecycle (start/stop, client list, broadcast, 10-second keepalive interval, offline message queue: 50-msg cap, 5-min TTL) in T383838core/takserver/src/commonMain/kotlin/.../TAKServerManager.kt
β€’ [X] T057 [US3] Implement T383838TAKDataPackageGenerator (export .zip with server certificates and connection config for ATAK/iTAK import) in T383838core/takserver/src/commonMain/kotlin/.../TAKDataPackageGenerator.kt
β€’ [X] T058 [US3] Add T383838PARTIAL_WAKE_LOCK acquisition in T383838MeshService when TAK server is active in T383838core/service/src/androidMain/kotlin/.../MeshService.kt
β€’ [X] T059 [US3] Wire T383838TAKMeshIntegration.start(scope) call from T383838MeshServiceOrchestrator in T383838core/service/src/commonMain/kotlin/.../MeshServiceOrchestrator.kt

Checkpoint: TAK server starts on port 8089, accepts mTLS connections, maintains keepalive, survives screen-off. Data package exportable.


Phase 6: User Story 4 β€” TAK Configuration UI (Priority: P2)

Goal: Compose Multiplatform settings UI for TAK module β€” server toggle, team/role selection, data package export, diagnostic test runner.

Independent Test: Navigate to TAK config, toggle server, change team/role, verify settings persist across app restart.

Implementation for User Story 4

β€’ [X] T060 [US4] Implement T383838TAKConfigItemList Compose UI (SwitchPreference for server toggle, DropDownPreference for team/role, TitledCard for status, export button, test runner button) in T383838feature/settings/src/commonMain/kotlin/.../radio/component/TAKConfigItemList.kt
β€’ [X] T061 [P] [US4] Implement T383838TakPermissionUtil expect interface in T383838feature/settings/src/commonMain/kotlin/.../tak/TakPermissionUtil.kt
β€’ [X] T062 [P] [US4] Implement T383838TakPermissionUtil Android actual (ACCESSLOCALNETWORK for API 37+) in T383838feature/settings/src/androidMain/kotlin/.../tak/TakPermissionUtil.kt
β€’ [X] T063 [P] [US4] Implement T383838TakPermissionUtil JVM actual (no-op) in T383838feature/settings/src/jvmMain/kotlin/.../tak/TakPermissionUtil.kt
β€’ [X] T064 [P] [US4] Implement T383838TakPermissionUtil iOS actual (no-op) in T383838feature/settings/src/iosMain/kotlin/.../tak/TakPermissionUtil.kt

Checkpoint: TAK config screen functional β€” server toggle works, team/role persists, test runner shows per-CoT-type byte sizes.


Phase 7: User Story 5 β€” Inbound Dual-Path Tolerance (Priority: P3)

Goal: V2-capable nodes decode and forward ALL inbound mesh traffic (both port 72 and port 78) to connected TAK clients.

Independent Test: Send a legacy TAKPacket (port 72) to a firmware 2.8.0+ node β†’ connected ATAK client receives the PLI as valid CoT XML.

Implementation for User Story 5

β€’ [X] T065 [US5] Verify inbound handler in T383838TAKMeshIntegration correctly decodes port 72 legacy packets and broadcasts to TAK clients (implemented as part of T049, verify independently)
β€’ [X] T066 [US5] Verify inbound handler in T383838TAKMeshIntegration correctly decompresses port 78 packets (including 0xFF uncompressed from TAK_TRACKER) and broadcasts to TAK clients

Checkpoint: No tactical data lost in mixed deployments. Both v1 and v2 inbound traffic decoded and forwarded correctly.


Phase 8: Polish & Cross-Cutting Concerns

Purpose: Verification, compliance, and documentation tasks that span all user stories.

β€’ [X] T067 [P] Add TAK-related string resources to T383838core/resources/src/commonMain/composeResources/values/strings.xml
β€’ [X] T068 [P] Review T383838TAKConfigItemList.kt against Meshtastic design standards β€” verify M3 components, accessibility (TalkBack), touch targets
β€’ [X] T069 [P] Confirm no logs, telemetry, or config changes expose PII, location data, secrets, or modify T383838core/proto submodule
β€’ [X] T070 [P] Run constitution-required verification: T383838./gradlew spotlessApply spotlessCheck detekt assembleDebug :core:takserver:allTests :feature:settings:allTests
β€’ [X] T071 [P] Verify all 12 test classes pass (89+ methods): T383838./gradlew :core:takserver:allTests
β€’ [X] T072 [P] Validate quickstart.md instructions produce successful build from clean checkout
β€’ [X] T073 Run T383838gh pr checks 5434 to confirm CI passes all checks
β€’ [X] T074 [P] [US3] Add test for offline message queue: verify FIFO eviction at 50-message cap, per-message TTL expiry after 5 minutes, and replay of queued messages on client reconnect
β€’ [X] T075 [P] [US4] Add test for ACCESSLOCALNETWORK permission denied on Android 17+: verify TAK server displays user-visible error and does not crash
β€’ [X] T076 [P] [US3] Add test for TAKServerJvm port-conflict error: verify graceful failure with user-visible error when port 8089 is already in use
β€’ [X] T077 [P] [US1] Add test for MAXDECOMPRESSEDSIZE boundary: verify T383838TakV2Compressor rejects payloads exceeding the decompression size limit
β€’ [X] T078 [P] [US1] Create T383838TAKMeshIntegrationTest.kt in T383838core/takserver/src/commonTest/ with lifecycle, inbound mesh, firmware gating, and GeoChat enrichment tests (10 tests)
β€’ [X] T079 [P] [US3] Add T383838broadcastRawXml tests to T383838TAKServerManagerTest.kt: verify forward-to-TAKServer when running and no-op when not running (2 tests)
β€’ [X] T080 [P] Restrict T383838TAKServerManagerImpl visibility to T383838internal in T383838TAKServerManager.kt β€” consumers use the T383838TAKServerManager interface via Koin


Dependencies & Execution Order

Phase Dependencies

β€’ Setup (Phase 1): No dependencies β€” can start immediately
β€’ Foundational (Phase 2): Depends on Phase 1 β€” BLOCKS all user stories
β€’ User Story 1 (Phase 3): Depends on Phase 2 β€” the MVP
β€’ User Story 2 (Phase 4): Depends on Phase 2 + shares T383838TAKMeshIntegration with US1
β€’ User Story 3 (Phase 5): Depends on Phase 2 β€” independent of US1/US2
β€’ User Story 4 (Phase 6): Depends on Phase 5 (needs TAKServerManager for toggle state)
β€’ User Story 5 (Phase 7): Depends on Phase 3 + Phase 4 (verification of dual-path handling)
β€’ Polish (Phase 8): Depends on all user stories being complete

User Story Dependencies

β€’ US1 (P1): After Phase 2 β€” no dependencies on other stories
β€’ US2 (P1): After Phase 2 β€” shares T383838TAKMeshIntegration.kt with US1 (co-implemented)
β€’ US3 (P2): After Phase 2 β€” independent (server infrastructure)
β€’ US4 (P2): After US3 (needs server lifecycle for toggle state)
β€’ US5 (P3): After US1 + US2 (verification of combined behavior)

Within Each User Story

β€’ Tests written alongside implementation (retroactive β€” both exist in PR)
β€’ Models/interfaces β†’ actual implementations β†’ integration β†’ verification
β€’ Platform actuals can be implemented in parallel (jvmAndroidMain, androidMain, jvmMain, iosMain)

Parallel Opportunities

β€’ All Phase 1 tasks T003-T006 can run in parallel
β€’ All Phase 2 tasks T008-T024 can run in parallel (independent files)
β€’ All US1 test tasks T025-T031 can run in parallel
β€’ Platform actuals within US1 (T033/T034, T040/T041, T042/T043/T044) can run in parallel
β€’ US3 server tasks T052/T053 can run in parallel (JVM vs iOS)
β€’ All US4 permission actuals T062/T063/T064 can run in parallel


Parallel Example: User Story 1

T282828
T8b949e# Launch all tests for US1 together:
Task: Ta5d6ff"CoTXmlParserTest in commonTest"
Task: Ta5d6ff"CoTXmlTest in commonTest"
Task: Ta5d6ff"CoTConversionTest in commonTest"
Task: Ta5d6ff"CoTDetailStripperTest in commonTest"
Task: Ta5d6ff"TAKPacketV2RawDetailTest in commonTest"
Task: Ta5d6ff"XmlUtilsTest in commonTest"
Task: Ta5d6ff"TAKDefaultsTest in commonTest"

T8b949e# Launch all platform actuals together:
Task: Ta5d6ff"TakV2Compressor jvmAndroidMain actual"
Task: Ta5d6ff"TakV2Compressor iosMain stub"
Task: Ta5d6ff"ZipArchiver jvmAndroidMain actual"
Task: Ta5d6ff"ZipArchiver iosMain stub"
Task: Ta5d6ff"AtakFileWriter androidMain actual"
Task: Ta5d6ff"AtakFileWriter jvmMain actual"
Task: Ta5d6ff"AtakFileWriter iosMain stub"



Implementation Strategy

MVP First (User Stories 1 + 2)

1. Complete Phase 1: Module setup + dependencies
2. Complete Phase 2: Shared models, constants, utilities
3. Complete Phase 3: US1 β€” Rich tactical data over mesh (v2 path)
4. Complete Phase 4: US2 β€” Legacy fallback (v1 path)
5. STOP and VALIDATE: Run all tests, verify PLI/marker round-trip on actual hardware

Incremental Delivery

1. Setup + Foundational β†’ Module compilable
2. US1 + US2 β†’ Full bidirectional mesh ↔ TAK bridge (MVP!)
3. US3 β†’ Reliable TAK server lifecycle
4. US4 β†’ User configuration UI
5. US5 β†’ Dual-path tolerance verification
6. Polish β†’ CI green, design compliance confirmed

Retroactive Verification (PR #5434)

Since this implementation already exists, use this task list as:
1. Verification checklist β€” confirm each task's output exists in the PR diff
2. Code review guide β€” trace requirements β†’ implementation β†’ tests
3. Regression detection β€” if future changes break a task's output, identify which user story is affected


Notes

β€’ [P] tasks = different files, no dependencies between them
β€’ [Story] label maps task to specific user story for traceability
β€’ This is a retroactive task list β€” PR #5434 implements all tasks
β€’ Verification: T383838./gradlew spotlessApply spotlessCheck detekt assembleDebug :core:takserver:allTests :feature:settings:allTests
β€’ Total implementation: 99 files changed, +4698 lines, 1 new KMP module (T383838core:takserver)

Served by rngit 1.5.0 - Generated in 0.04s